/*
 * Copyright the original author or authors.
 * 
 * Licensed under the MOZILLA PUBLIC LICENSE, Version 1.1 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.mozilla.org/MPL/MPL-1.1.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.kairos.engine
{
	import com.bourre.commands.Suspendable;
	import com.bourre.transitions.TickListener;	

	/**
	 * <code>RTAnimation</code> interface provides basic rules that
	 * animation object may follow when dealing with a <code>RTBeacon</code>.
	 * <code>RTAnimation</code> is a <code>TickListener</code> which extends
	 * controls that class have to provide.
	 * 
	 * <p>More than methods such <code>start</code>, <code>stop</code>, and
	 * <code>isPlaying</code>, a <code>RTAnimation</code> provides methods
	 * to swap the reference beacon of the object or to modify the local speed
	 * of the object animation.</p>
	 * 
	 * <p>See the <code>RTObject</code> class for a concret implementation
	 * of the <code>RTAnimation</code> interface. <code>RTObject</code> is
	 * an abstract implementation, so extend it to create your own real time
	 * animated objects.</p> 
	 * 
	 * @author 	Cédric Néhémie
	 * @see		RTBeacon
	 */
	public interface RTAnimation extends TickListener, Suspendable
	{
		/**
		 * Defines on which beacon instance the object will run.
		 * 
		 * <p>If the object is currently running the concret class
		 * have to unregister itself from the object beacon. If you omit
		 * to unregister the object, the <code>onEnterFrame</code> method
		 * will be called by the two beacon.</p>
		 * 
		 * <p>Use that method if you want to animate object independently
		 * of the global <code>RTBeacon</code> instance.</p>
		 * 
		 * <p>If the passed-in beacon is null the object have to throw
		 * a <code>NullPointerException</code> error.</p>
		 * 
		 * <p>Subclass that don't support the <code>setTickBeacon</code>
		 * method have to throw an <code>UnsupportedOperationException</code>
		 * error.</p>
		 * 
		 * <p>The example below show how to implements the <code>setTickBeacon</code>
		 * correctly in a concret <code>RTAnimation</code> class. That example is taken
		 * from the <code>RTObject</code> class.</p>
		 * 
		 * <listing>public function setTickBeacon ( beacon : RTBeacon ) : void
		 * {
		 * 	if( !beacon ) 
		 * 		throw new NullPointerException ( "Trying to set a null beacon for " + this );
		 * 	
		 * 	if( _bIsPlaying )
		 * 	{ 
		 * 		stop();
		 * 		_oBeacon = beacon;
		 * 		start();
		 * 	}
		 * 	else
		 * 	{
		 * 		_oBeacon = beacon;
		 * 	}
		 * }
		 * </listing>
		 * 
		 * @param 	beacon <code>RTBeacon</code> or subclass instance.
		 * @throws 	<code>UnsupportedOperationException</code> — The <code>setTickBeacon</code>
		 * 			method isn't supported by the current object.
		 * @throws 	<code>NullPointerException</code> — The passed-in beacon is null.
		 */
		function setTickBeacon( beacon : RTBeacon ) : void;
		
		/**
		 * Returns the current beacon onto which the object run.
		 * 
		 * <p>Subclass that don't support the <code>getTickBeacon</code>
		 * method have to throw an <code>UnsupportedOperationException</code>
		 * error.</p>
		 * 
		 * @return  <code>RTBeacon</code> used by the object.
		 * @throws 	<code>UnsupportedOperationException</code> — The <code>getTickBeacon</code>
		 * 			method isn't supported by the current object.
		 */
		function getTickBeacon() : RTBeacon;
		
		/**
		 * Defines the local speed factor for the current object. Local speed works
		 * as a multiplier for the time step value received from the beacon - as the
		 * <code>setGlobalSpeed</code> feature of the RTBeacon.
		 * 
		 * <p>The local and global speed works the same. Both they multiply the time
		 * step by their own speed value. Resulting that you can rescale time for
		 * a specific object or for all objects at the same time. The effects of
		 * both parameters are cumulated with all other time adjustments (time limit
		 * or smoothness).</p>
		 * 
		 * <p>Subclass can accept a value lower or equals than 0 if their equation
		 * could support it, in many case a value of 0 will stop the animation.
		 * All objects that don't support this feature have to throw
		 * a <code>RangeError</code>.</p>
		 * 
		 * <p>Subclass that don't support the <code>setLocalSpeed</code>
		 * method have to throw an <code>UnsupportedOperationException</code>.</p>
		 * 
		 * @param 	rate 	float number used as multiplier for the current time step
		 * @throws 	<code>UnsupportedOperationException</code> — The <code>setLocalSpeed</code>
		 * 			method isn't supported by the current object.
		 * @throws 	<code>RangeError</code> — The value specified in <code>setLocalSpeed</code>
		 * 			isn't supported by the current object.	
		 */
		function setLocalSpeed ( rate : Number ) : void;
			
		/**
		 * Returns the current local speed factor of the object.
		 * 
		 * <p>Subclass that don't support the <code>setLocalSpeed</code>
		 * method have to throw an <code>UnsupportedOperationException</code>.</p>
		 * 
		 * @return 	<code>Number</code> local speed of the object.
		 * @throws 	<code>UnsupportedOperationException</code> — The <code>getLocalSpeed</code>
		 * 		   	method isn't supported by the current object.
		 */
		function getLocalSpeed () : Number;
	}
}